package com.fm.base.struct;

public abstract class HashTable<E> {
	public interface HashNode<E> {
		E getElement();
		HashNode<E> getNext();
		void setNext(HashNode<E> next);
	}

	protected int size = 0;
	protected int threshold; // 阈值
	protected float loadFactor;
	protected float expandFactor;
	protected HashNode<E>[] table;

	abstract protected int hash(E element);
	abstract protected void reHash();

	protected int render(int a, int b) {
		a = a % b;
		return a < 0 ? (a + b) : a;
	}

	protected HashNode<E> getNode(E key) {
		int hash = hash(key);
		HashNode<E> node = table[render(hash, table.length)];
		if (node != null) {
			while (node != null) {
				if (hash == hash(node.getElement()) && node.getElement().equals(key)) {
					return node;
				}
				node = node.getNext();
			}
		}
		return null;
	}

	protected HashNode<E> removeNode(E key) {
		int hash = hash(key);
		int index = render(hash(key), table.length);
		HashNode<E> node = table[index];
		if (node != null) {
			HashNode<E> preEntry = null;
			while (node != null) {
				if (hash == hash(node.getElement()) && node.getElement().equals(key)) {
					if (preEntry == null) {
						table[index] = node.getNext();
					} else {
						preEntry.setNext(node.getNext());
					}
					size--;
					return node;
				}
				preEntry = node;
				node = node.getNext();
			}
		}
		return null;
	}

	public int size() {
		return size;
	}

	public boolean isEmpty() {
		return size == 0;
	}
}
